﻿using CoreLims.Models.CoreLims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Scripting.Utils;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace CoreLims.Controllers
{
    public class UserManagerController : Controller
    {
        private readonly CoreLimsContext dbContext;
        private UserManager<IdentityUser> _UserManager;
        private RoleManager<IdentityRole> _RoleManager;
        private SignInManager<IdentityUser> SignInManager;

        public UserManagerController(CoreLimsContext context, UserManager<IdentityUser> usrManager, RoleManager<IdentityRole> roleManager, SignInManager<IdentityUser> signinManager)
        {
            dbContext = context;
            _UserManager = usrManager;
            _RoleManager = roleManager;
            SignInManager = signinManager;
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<RedirectToActionResult> UserLogin(string UserName, string Password)
        {
            try
            {
                // 第三个参数：指示浏览器关闭后，登录 cookie 是否应该保留的标志。第四个参数：多次登录失败后，是否锁定账号
                var result = await SignInManager.PasswordSignInAsync(UserName, Password, false, true);

                if (result.Succeeded)
                {
                    return RedirectToAction(actionName: "Index", controllerName: "Home");
                }
                else
                {
                    return RedirectToAction(actionName: "Login", controllerName: "Home", new { ErrorMessage = "用户名或密码错误！" });
                }
            }
            catch (Exception ex)
            {
                var ruser = Common.User.getUserByIdentityName(dbContext, "admin");
                var audit = Audit.newAudit;
                audit.EventName = "用户登录";
                audit.TableName = "UserLogin 函数";
                audit.RemindUserId = ruser.Id;
                audit.RemindUserName = ruser.FullName;
                audit.Explain = ex.Message.Substring(0, ex.Message.Length > 1000 ? 1000 : ex.Message.Length);
                dbContext.Add(audit);
                dbContext.SaveChanges();
            }
            return RedirectToAction(actionName: "Index", controllerName: "Home");
        }

            [HttpPost]
        [ValidateAntiForgeryToken]  // 退出登录
        public async Task<IActionResult> LogOut()
        {
            await SignInManager.SignOutAsync();
            return RedirectToAction(actionName: "Index", controllerName: "Home");
        }

        [HttpPost]
        public async Task<string> CreateUser(string UserName) // 添加用户
        {
            var user = new IdentityUser { UserName = UserName };

            IdentityResult result = await _UserManager.CreateAsync(user, "corelims123");
            if (result.Succeeded)
            {
                var iuser = await _UserManager.FindByNameAsync(UserName);
                var id = iuser.Id;
                CommonUser cuser = new CommonUser { Id = id, IdentityName = UserName };
                cuser.AddUser(dbContext);
                return "新用户添加成功！";
            }
            foreach (IdentityError err in result.Errors)
            {
                return err.Code == "DuplicateUserName" ? "该用户名已存在！" : err.Description;
            }
            return null;
        }

        [HttpPost]
        [ValidateAntiForgeryToken]  // 用户自己注册账户时使用
        public async Task<string> Register(string UserName, string Password, string rePassword)
        {
            if (Password != rePassword)
                return "两次输入的密码不一致！";

            var user = new IdentityUser { UserName = UserName };

            IdentityResult result = await _UserManager.CreateAsync(user, Password);
            if (result.Succeeded)
            {
                var iuser = await _UserManager.FindByNameAsync(UserName);
                var id = iuser.Id;
                CommonUser cuser = new CommonUser { Id = id, IdentityName = UserName };
                cuser.AddUser(dbContext);
                return "新用户注册成功！";
            }
            foreach (IdentityError err in result.Errors)
            {
                return err.Description.Contains("already taken") ? "该用户名已注册！" : err.Description;
            }
            return null;
        }

        [HttpPost]
        public async Task<string> DeleteUser(string UserName)
        {
            var user = await _UserManager.FindByNameAsync(UserName);
            if (user != null)
            {
                await _UserManager.DeleteAsync(user);
                var cuser = Common.User.getUserById(dbContext, user.Id);
                dbContext.Remove(cuser);
                dbContext.SaveChanges();

                return "用户删除成功！";
            }
            return null;
        }

        [Authorize(Roles = "Admin")]
        public ViewResult UserManager() => View();

        [HttpPost]
        public JsonResult GetUsers(string limit, string offset) // 获取所有用户
        {
            var list = from iuser in _UserManager.Users.ToList().Skip(int.Parse(offset)).Take(int.Parse(limit))
                       join cuser in dbContext.User on iuser.Id equals cuser.Id
                       select new { iuser.UserName, cuser.FullName, cuser.Head, cuser.Signature };

            var res = new Common.PageHelper();
            res.total = _UserManager.Users.Count();
            res.rows = list.ToArray();

            return Json(res);
        }

        [HttpPost]
        public JsonResult GetUserIdAndFullname() // 获取所有用户的ID和姓名
        {
            var list = dbContext.User.OrderBy(s => s.FullName)
                .Select(s => new { s.Id, s.FullName })
                .ToList();
            return Json(list);
        }

        [HttpPost]
        public JsonResult GetUserIdAndFullnameByGroup(string GroupId) // 根据"工作组"ID,获取组内用户的ID和姓名
        {
            var list = dbContext.User.OrderBy(s => s.FullName)
                .Select(s => new { s.Id, s.FullName })
                .ToList();
            return Json(list);
        }

        [HttpPost]
        public async Task<string> UpdatePasswork(string UserName, string Password) // 更新密码
        {
            var user = await _UserManager.FindByNameAsync(UserName);
            var re = await _UserManager.RemovePasswordAsync(user); //清空旧密码。
            IdentityResult result = await _UserManager.AddPasswordAsync(user, Password); //加入新密码
            if (result.Succeeded)
            {
                return "密码修改成功！";
            }
            foreach (IdentityError err in result.Errors)
            {
                return err.Description;
            }
            return null;
        }

        [HttpPost]
        public async Task<JsonResult> GetUserInfo(string IdenUserName) // 获得用户简历
        {
            var iuser = await _UserManager.FindByNameAsync(IdenUserName);
            var user = Common.User.getUserById(dbContext, iuser.Id);
            return Json(user);
        }

        [HttpPost]
        public string UpdateUserInfo(string jsonStr) // 更新用户简历
        {
            var newuser = JsonConvert.DeserializeObject<CommonUser>(jsonStr);  //反序列化，字符串转换为类
            var user = Common.User.getUserById(dbContext, newuser.Id);
            user.FullName = newuser.FullName;
            user.JobTitle = newuser.JobTitle;
            user.DateOfBirth = newuser.DateOfBirth;
            user.EmploymentDate = newuser.EmploymentDate;
            user.Nation = newuser.Nation;
            user.Sex = newuser.Sex;
            user.NativePlace = newuser.NativePlace;
            user.Education = newuser.Education;
            user.Politic = newuser.Politic;
            user.Major = newuser.Major;
            user.PhoneNumber = newuser.PhoneNumber;
            user.WentToSchool = newuser.WentToSchool;
            user.Email = newuser.Email;
            user.Address = newuser.Address;
            user.EducationalBackground = newuser.EducationalBackground;
            user.WorkExperience = newuser.WorkExperience;
            user.SkillCertificate = newuser.SkillCertificate;
            user.Rewards = newuser.Rewards;
            user.SelfIntroduction = newuser.SelfIntroduction;

            dbContext.Update(user);
            dbContext.SaveChanges();
            return "用户信息更新成功！";
        }

        [Authorize(Roles = "Admin")]
        public ViewResult RolesManager() => View();

        [HttpPost]
        public JsonResult GetRoles(string limit, string offset) // 获得角色列表
        {
            var list = _RoleManager.Roles.ToList()
                       .Skip(int.Parse(offset))
                       .Take(int.Parse(limit));

            var res = new Common.PageHelper();
            res.total = _RoleManager.Roles.Count();
            res.rows = list.ToArray();

            return Json(res);
        }

        [HttpPost]
        public async Task<string> AddRole(string RoleName)
        {
            bool exist = await _RoleManager.RoleExistsAsync(RoleName);
            if (!exist)
            {
                var element = new IdentityRole();
                element.Name = RoleName;
                var result = await _RoleManager.CreateAsync(element);
                return "角色添加成功！";
            }
            return "角色已存在！";
        }

        [HttpPost]
        public async Task<string> RemoveRole(string RoleId)
        {
            var role = await _RoleManager.FindByIdAsync(RoleId);
            var result = await _RoleManager.DeleteAsync(role);
            if (result.Succeeded)
            {
                return "角色删除成功！";
            }
            return "角色添加失败！";
        }

        [HttpPost]
        public async Task<JsonResult> GetUserRoles(string limit, string offset, string UserName) // 获得用户所属角色列表
        {
            var user = await _UserManager.FindByNameAsync(UserName);
            var userRoles = await _UserManager.GetRolesAsync(user);

            var list = _RoleManager.Roles.ToList()
                       .Select(s => new { s.Id, s.Name, UserRole = userRoles.Contains(s.Name)?true:false })
                       .Skip(int.Parse(offset))
                       .Take(int.Parse(limit));

            var res = new Common.PageHelper();
            res.total = _RoleManager.Roles.Count();
            res.rows = list.ToArray();

            return Json(list);
        }

        [HttpPost]
        public async Task<string> SetUserRole(string UserName, string RoleName) // 设置用户所属角色关系
        {
            var user = await _UserManager.FindByNameAsync(UserName);
            var isinrole = await _UserManager.IsInRoleAsync(user, RoleName);

            if (isinrole)
                await _UserManager.RemoveFromRoleAsync(user, RoleName);
            else
                await _UserManager.AddToRoleAsync(user, RoleName);

            return "设置成功！";
        }

    }
}
